package myexchange

import myexchange.PlayerActionType;

import org.springframework.transaction.annotation.Transactional;

class TurnService {
	
	CardService cardService
	ExchangeService exchangeService
	enum TurnState { NEW, STARTED, READY, TRADING, CARD }

	@Transactional
	public void enqueAction(Player player, Card card, Trade trade, PlayerActionType type){	
		PlayerAction pa = new PlayerAction([
			player:player,
			turn:getCurrentTurn(),
			type:type,
			]).save()
		if(card){
			pa.addToCards(card)
		}
		if(trade){
			pa.addToTrades(trade)
		}
		pa.save()
	}
	
	@Transactional
	public endTurn(){
		executeQueue()
		Turn turn = getCurrentTurn()
		new Turn([number:turn.number+1]).save()
	}
	
	public startTurn(Player player){
		enqueAction(player, null, null, PlayerActionType.START)
	}
	
	@Transactional
	private void executeQueue(){
		def actions = PlayerAction.findAllWhere(
				turn:getCurrentTurn()
			)
		Collections.shuffle(actions)
		for(PlayerAction action : actions){
			switch (action.type) {
			case PlayerActionType.CARD:
				for(Card card : action.cards){
					cardService.executeCard(card.id, action.player)
				}
				break;

			case PlayerActionType.TRADE:
				for(Trade trade : action.trades){
					exchangeService.tradeShare(trade.player.id, trade.share, trade.quantity)
				}
				break;

			default:
				break;
			}
		}
	}

	Turn getCurrentTurn(){
		Turn turn
		def turns = Turn.list(max:1, sort:"number", order:"desc")
		if(turns){
			turn = turns.first()
		}else{
			turn = new Turn(number:1).save()
		}
		return turn
	}
	
	TurnState getTurnState(Player player){
		TurnState state = TurnState.NEW
		def actions = PlayerAction.findAllWhere([
				player:player,
				turn:getCurrentTurn()
			])
		Map order = [
				(PlayerActionType.START):1, 
				(PlayerActionType.CARD):2,
				(PlayerActionType.TRADE):3, 
				(PlayerActionType.END):4, 
			]
		int importance = 0
		for(PlayerAction action : actions){
			int weight = order[action.type]
			importance =  Math.max(weight, importance)
		}
		Map states = [
				0:TurnState.NEW, 
				1:TurnState.STARTED, 
				2:TurnState.CARD,
				3:TurnState.TRADING, 
				4:TurnState.READY, 
			]
		return states[importance]
	}	
}
